#include <iostream>

enum OldEnum{Yes, No};                  // old style
enum class NewEnum{Yes, No};            // new style
enum struct NewEnum2{Yes, No};          // new style
enum struct NewEnum3 : char{Yes, No};   // new style
enum struct NewEnum4 : int{Yes, No};    // new style

template<typename T>
std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
{
    return stream << static_cast<typename std::underlying_type<T>::type>(e);
}

int main()
{
    OldEnum e1 = Yes;
    if(e1 == 0) {
        std::cout << "e1 = 0" << std::endl;
    }
    std::cout << "e1 = " << e1 << std::endl;

    // NewEnum e2 = No;                 // 错误：使用了 OldEnum 中 No 值
    // NewEnum e2 = 0;                  // 错误：不支持隐式转换
    NewEnum e2 = NewEnum::No;           // 正确
    // 错误：不支持隐式转换，无法直接输出
    // 当重载 << 运算符之后正确
    std::cout << "e2 = " << e2 << std::endl;
    /* 
    if(e2 == 1) {               // 错误：不支持隐式转换比较
        std::cout << "e2 = 1" << std::endl;
    }
    */

    std::cout << "sizeof(NewEnum2::Yes) = " << sizeof(NewEnum2::Yes) << std::endl;
    std::cout << "sizeof(NewEnum3::Yes) = " << sizeof(NewEnum3::Yes) << std::endl;
    std::cout << "sizeof(NewEnum4::Yes) = " << sizeof(NewEnum4::Yes) << std::endl;

    return 0;
}